#!/bin/bash

include "test.sh"

SCOPE_DESTROY_COMMANDS=()

function Scope::AddDestroyCommand()
{
    trap 'Scope::_Exit' RETURN
    SCOPE_DESTROY_COMMANDS=("${#BASH_LINENO[*]}" "$#" "$@" "${SCOPE_DESTROY_COMMANDS[@]}")
}

function Scope::AddDestroyCommandForUpper()
{
    trap 'Scope::_Exit' RETURN
    local uplevel="${1:-0}"; shift
    SCOPE_DESTROY_COMMANDS=("$((${#BASH_LINENO[*]} - $uplevel))" "$#" "$@" "${SCOPE_DESTROY_COMMANDS[@]}")
}

function Scope::_Exit()
{
    while [ "${#SCOPE_DESTROY_COMMANDS[*]}" != "0" ] &&
        [ "${#BASH_LINENO[*]}" == "${SCOPE_DESTROY_COMMANDS[0]}" ]; do
        unset SCOPE_DESTROY_COMMANDS[0]
        local command="${SCOPE_DESTROY_COMMANDS[2]}"
        local i
        for (( i = 1; i < SCOPE_DESTROY_COMMANDS[1]; i++ )); do
            command+=" ${SCOPE_DESTROY_COMMANDS[$(($i + 2))]}"
            unset SCOPE_DESTROY_COMMANDS[$(($i + 2))]
        done
        unset SCOPE_DESTROY_COMMANDS[1]
        unset SCOPE_DESTROY_COMMANDS[2]
        eval "$command"
        SCOPE_DESTROY_COMMANDS=("${SCOPE_DESTROY_COMMANDS[@]}")
    done
}

function Scope::_Test1()
{
    local pass
    function Scope::Test1::A()
    {
        function Scope::Test1::A::A()
        {
            Scope::AddDestroyCommand "pass+=' A::A'"
            test::var_should_be pass ''
            pass='OK'
            test::var_should_be pass 'OK'
        }
        test::var_should_be pass ''
        Scope::AddDestroyCommand "pass+=' A'"
        Scope::Test1::A::A
        test::var_should_be pass 'OK A::A'
    }

    test::var_should_be pass ''
    Scope::Test1::A
    test::var_should_be pass 'OK A::A A'
    trap - RETURN
}
test::register_test Scope::_Test1
